package com.pug.gateway.filter;

import cn.hutool.core.util.StrUtil;
import com.pug.gateway.service.AuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * @author RenGaoshuai
 * @date 2023/5/12 17:16
 * @description 鉴权过滤器
 */
@Configuration
@Order(1)
@Slf4j
public class AuthorizationFilter implements GlobalFilter, Ordered {

    private static final String APPTOKEN = "appToken";
    public static final String AUTHORIZATION = "Authorization";
    public static final String BEARER = "Bearer";

    @Value("${ecs.conf.authorization.enable}")
    private Boolean enableAuthorization;

    @Autowired
    private AuthService authService;


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {


        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();

        log.info("进入鉴权过滤器--->url:{}", request.getURI());

        if (!enableAuthorization){
            return chain.filter(exchange);
        }

        String method = request.getMethodValue();
        String url = request.getPath().value();

        //不需要鉴权的url
        if (authService.ignoreAuthentication(url)) {
            //放行
            return chain.filter(exchange);
        }

        //获取头部authorization字段
        String authorization = headers.getFirst(AUTHORIZATION);
        //获取头部appToken字段
        String appToken = request.getHeaders().getFirst(APPTOKEN);

        //根据apptoken生成authorization
        if (StrUtil.isBlank(authorization) && StrUtil.isNotBlank(appToken)) {
            if (1 == 1) {

                //TODO 完善密钥
                //根据apptoken查对应的密钥

                //根据密钥生成authorization
                return chain.filter(exchange);
            } else {
                return unauthorized(exchange);
            }
        }

        //认证
        if (authService.permission(authorization, method, url)) {
            //认证成功,进入下一个过滤器

            //TODO 完善认证
            return chain.filter(exchange);
        }

        //认证未通过
        return unauthorized(exchange);
    }


    /**
     * 网关拒绝，返回401
     *
     * @param
     */
    private Mono<Void> unauthorized(ServerWebExchange serverWebExchange) {
        serverWebExchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        DataBuffer buffer = serverWebExchange.getResponse()
                .bufferFactory().wrap(HttpStatus.UNAUTHORIZED.getReasonPhrase().getBytes());
        return serverWebExchange.getResponse().writeWith(Flux.just(buffer));
    }

    @Override
    public int getOrder() {
        return 1;
    }
}
